#ifndef __COMM_STRUCT_H__
#define __COMM_STRUCT_H__
#include "base/macro.h"
#include "base/atomic.h"
#include "base/base_def.h"
#include "log/log.h"

namespace weilin {

	enum Status {
		STATUS_IDLE = 0,
		STATUS_INIT = 1,
		STATUS_START = 2,
		STATUS_STOP = 3,
		STATUS_FAIL = 4
	};

	enum SocketStatus
	{
		SOCKET_IDLE = 0,
		SOCKET_CONNECTING = 1,
		SOCKET_CONNECTED = 2,
		SOCKET_CONNECTING_TIMEOUT = 3,
		SOCKET_COLOSING = 4,
		SOCKET_COLOSED = 5,
	};

	enum StopMthod
	{
		STOP_FORCE = 1,
		STOP_PEACE = 2,
	};


	enum ChannelType
	{
		CHANNEL_CMD = 1,
		CHANNEL_HTTP = 2
	};

	enum PacketType
	{
		PACKET_REQUEST = 1,
		PACKET_RESPONSE = 2
	};

	struct Header
	{
		string key;
		string value;
		void Reset()
		{
			key.clear();
			value.clear();
		}
	};

	enum CmdConsumerStatus
	{
		CMD_IDLE = 1,
		CMD_KEY = 2,
		CMD_VALUE = 3,
		CMD_NEW_LINE_HEAD_CHAR = 4,
		CMD_NEW_LINE_BODY_CHAR = 5,
		CMD_BODY = 6
	};

	enum HttpConsumerStatus
	{
		HTTP_IDLE = 1,
		HTTP_NEW_LINE_KEY_CHAR = 2,
		HTTP_KEY = 3,
		HTTP_SPACE = 4,
		HTTP_VALUE = 5,
		HTTP_NEW_LINE_HEAD_CHAR = 6,
		HTTP_NEW_LINE_BODY_CHAR = 7,
		HTTP_BODY = 8
	};

	struct HttpTop
	{
		string m_method;
		string uri;
		string version;
		void Reset();
	};

	enum ConsumerRetStatus
	{
		CONSUM_RET_SUCCESS = 1,
		CONSUM_RET_CONTINUE = 2,
		CONSUM_RET_FAIL = 3
	};

	enum SendRecvStatus
	{
		SEND_FAIL_FOR_CLOSE = 1,
		SEND_FAIL_FOR_TIMEOUT = 2,
		RECV_FAIL_FOR_CLOSE = 3,
		RECV_FAIL_FOR_TIMEOUT = 4,
		SEND_RECV_SECCESS = 5,
		SEND_FAIL_FOR_SEQ = 6
	};

	enum SendStatus
	{
		SEND_ERROR_FOR_CLOSE = 1,
		SEND_ERROR_FOR_SEQ = 2
	};

	struct WaitEvent
	{
	public:
		WaitEvent();
		void Wait();
		void Signal();
	private:
		mutex_lock m_mutex;
		mutex_condition  m_cond;
		bool m_is_need_wait;
	};

	template<typename T>
	class ObjCount
	{
	public:
		ObjCount()
		{
			AtomicIncrement<uint32_t>(&s_obj_count);
			LOG(INFO) << "gouzhao s_obj_count: " << s_obj_count;
		}
		virtual ~ObjCount()
		{
			AtomicDecrement<uint32_t>(&s_obj_count);
			LOG(INFO) << "xigou s_obj_count: " << s_obj_count;
		}
	private:
		static uint32_t s_obj_count;
	};
	template <typename T> uint32_t ObjCount<T>::s_obj_count = 0;
}

#endif
